x11: Keep track of the exact size in X pixels of windows
authorOwen W. Taylor <otaylor@fishsoup.net>
Thu, 6 Nov 2014 22:17:45 +0000 (17:17 -0500)
committerAlexander Larsson <alexl@redhat.com>
Thu, 20 Nov 2014 11:38:04 +0000 (12:38 +0100)
Keep track of the exact size of X windows in underlying pixels; we
generally use the scaled size instead, but to properly handle the GL
viewport for windows that aren't a multiple of window_scale,
we need to know the real size.

https://bugzilla.gnome.org/show_bug.cgi?id=739750

gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkgeometry-x11.c
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkwindow-x11.h

index d5cf7d666f74399e2de9144a5d26947f32cb087a..d6543c1e384a9fdb6b83577223839583642ffea6 100644 (file)
@@ -767,11 +767,13 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
                           : ""));
       if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
         {
+          window_impl->unscaled_width = xevent->xconfigure.width;
+          window_impl->unscaled_height = xevent->xconfigure.height;
          window->width = (xevent->xconfigure.width + window_impl->window_scale - 1) / window_impl->window_scale;
          window->height = (xevent->xconfigure.height + window_impl->window_scale - 1) / window_impl->window_scale;
 
          _gdk_window_update_size (window);
-         _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
+         _gdk_x11_window_update_size (window_impl);
          _gdk_x11_screen_size_changed (screen, xevent);
         }
 
@@ -826,11 +828,13 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
            {
              window->x = event->configure.x;
              window->y = event->configure.y;
+              window_impl->unscaled_width = xevent->xconfigure.width;
+              window_impl->unscaled_height = xevent->xconfigure.height;
               window->width = event->configure.width;
               window->height = event->configure.height;
 
              _gdk_window_update_size (window);
-             _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
+             _gdk_x11_window_update_size (window_impl);
 
              if (window->resize_count >= 1)
                {
index cfcbec891aa4b6d318bd244b62f235fde4fb6821..5fac8fd766b018a01174a264bd3271f033e63734 100644 (file)
@@ -62,6 +62,8 @@ _gdk_x11_window_move_resize_child (GdkWindow *window,
 
   window->x = x;
   window->y = y;
+  impl->unscaled_width = width * impl->window_scale;
+  impl->unscaled_height = height * impl->window_scale;
   window->width = width;
   window->height = height;
 
index ec4eead3621158210271953da9075523e79d0a21..c4b90af74b65d707422ba33be5151db7453fbd18 100644 (file)
@@ -194,8 +194,7 @@ _gdk_x11_window_update_size (GdkWindowImplX11 *impl)
   if (impl->cairo_surface)
     {
       cairo_xlib_surface_set_size (impl->cairo_surface,
-                                   gdk_window_get_width (impl->wrapper) * impl->window_scale,
-                                   gdk_window_get_height (impl->wrapper) * impl->window_scale);
+                                   impl->unscaled_width, impl->unscaled_height);
     }
 }
 
@@ -734,6 +733,8 @@ _gdk_x11_screen_init_root_window (GdkScreen *screen)
   window->y = 0;
   window->abs_x = 0;
   window->abs_y = 0;
+  impl->unscaled_width = WidthOfScreen (x11_screen->xscreen);
+  impl->unscaled_height = HeightOfScreen (x11_screen->xscreen);
   window->width = WidthOfScreen (x11_screen->xscreen) / impl->window_scale;
   window->height = HeightOfScreen (x11_screen->xscreen) / impl->window_scale;
   window->viewable = TRUE;
@@ -1080,6 +1081,9 @@ _gdk_x11_display_create_window_impl (GdkDisplay    *display,
         window->height = 32767 /  impl->window_scale;
     }
 
+  impl->unscaled_width = window->width * impl->window_scale;
+  impl->unscaled_height = window->height * impl->window_scale;
+
   impl->xid = XCreateWindow (xdisplay, xparent,
                              (window->x + window->parent->abs_x) * impl->window_scale,
                              (window->y + window->parent->abs_y) * impl->window_scale,
@@ -1229,6 +1233,8 @@ gdk_x11_window_foreign_new_for_display (GdkDisplay *display,
 
   win->x = attrs.x / impl->window_scale;
   win->y = attrs.y / impl->window_scale;
+  impl->unscaled_width = attrs.width;
+  impl->unscaled_height = attrs.height;
   win->width = attrs.width / impl->window_scale;
   win->height = attrs.height  / impl->window_scale;
   win->window_type = GDK_WINDOW_FOREIGN;
@@ -1789,13 +1795,15 @@ window_x11_resize (GdkWindow *window,
 
       if (impl->override_redirect)
         {
+          impl->unscaled_width = width * impl->window_scale;
+          impl->unscaled_height = height * impl->window_scale;
           window->width = width;
           window->height = height;
           _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
         }
       else
         {
-          if (width != window->width || height != window->height)
+          if (width * impl->window_scale != impl->unscaled_width || height * impl->window_scale != impl->unscaled_height)
             window->resize_count += 1;
         }
     }
@@ -1835,6 +1843,8 @@ window_x11_move_resize (GdkWindow *window,
           window->x = x;
           window->y = y;
 
+          impl->unscaled_width = width * impl->window_scale;
+          impl->unscaled_height = height * impl->window_scale;
           window->width = width;
           window->height = height;
 
@@ -1842,7 +1852,7 @@ window_x11_move_resize (GdkWindow *window,
         }
       else
         {
-          if (width != window->width || height != window->height)
+          if (width * impl->window_scale != impl->unscaled_width || height * impl->window_scale != impl->unscaled_height)
             window->resize_count += 1;
         }
     }
@@ -1922,17 +1932,30 @@ _gdk_x11_window_set_window_scale (GdkWindow *window,
                  (window->x + window->parent->abs_x) * impl->window_scale,
                  (window->y + window->parent->abs_y) * impl->window_scale);
   else if (WINDOW_IS_TOPLEVEL(window))
-    XResizeWindow (GDK_WINDOW_XDISPLAY (window),
-                   GDK_WINDOW_XID (window),
-                   window->width * impl->window_scale,
-                   window->height * impl->window_scale);
+    {
+      if (impl->override_redirect)
+        {
+          impl->unscaled_width = window->width * impl->window_scale;
+          impl->unscaled_height = window->height * impl->window_scale;
+        }
+
+      XResizeWindow (GDK_WINDOW_XDISPLAY (window),
+                     GDK_WINDOW_XID (window),
+                     window->width * impl->window_scale,
+                     window->height * impl->window_scale);
+    }
   else
-    XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
-                       GDK_WINDOW_XID (window),
-                       (window->x + window->parent->abs_x) * impl->window_scale,
-                       (window->y + window->parent->abs_y) * impl->window_scale,
-                       window->width * impl->window_scale,
-                       window->height * impl->window_scale);
+    {
+      impl->unscaled_width = window->width * impl->window_scale;
+      impl->unscaled_height = window->height * impl->window_scale;
+
+      XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
+                         GDK_WINDOW_XID (window),
+                         (window->x + window->parent->abs_x) * impl->window_scale,
+                         (window->y + window->parent->abs_y) * impl->window_scale,
+                         window->width * impl->window_scale,
+                         window->height * impl->window_scale);
+    }
 
   gdk_window_invalidate_rect (window, NULL, TRUE);
 
index d66e8740f77a1bf0a0d2a3143b84d73505b9bbb7..2bc2417d8b64e1ca9040584cbe8f71339fb55c6a 100644 (file)
@@ -76,6 +76,14 @@ struct _GdkWindowImplX11
 
   gint window_scale;
 
+  /* Width and height not divided by window_scale - this matters in the
+   * corner-case where the window manager assigns us a size that isn't
+   * a multiple of window_scale - for example for a maximized window
+   * with an odd-sized title-bar.
+   */
+  gint unscaled_width;
+  gint unscaled_height;
+
   cairo_surface_t *cairo_surface;
 
 #if defined (HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES)